package com.major.dawn.aqs;

import com.major.dawn.linkList.LinkedList;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;


public class MyBoundedBuff {


    final LinkedList putWaiter = new LinkedList();

    final LinkedList takeWaiter = new LinkedList();

    final Object[] items = new Object[3];

    final AtomicInteger count = new AtomicInteger();
    int putptr, takeptr;

    // 生产者方法，往数组里面写数据
    public void put(Object x) throws InterruptedException {

        try {
            while (count.get() == items.length) {
                putWaiter.addAtTail(Thread.currentThread());
                LockSupport.park();
            }

            items[putptr] = x;
            if (++putptr == items.length) {
                putptr = 0;
            }
            count.getAndIncrement();
            // 因为放入了一个数据，数组肯定不是空的了
            // 此时唤醒等待这notEmpty条件上的线程
            Thread thread = takeWaiter.get(0);
            if (thread != null) {
                LockSupport.unpark(thread);
            }

        } finally {

        }
    }

    // 消费者方法，从数组里面拿数据
    public Object take() throws InterruptedException {

        try {
            while (count.get() == 0) {
                takeWaiter.addAtTail(Thread.currentThread());
                LockSupport.park();
            }

            Object x = items[takeptr];
            if (++takeptr == items.length) {
                takeptr = 0;
            }
            count.decrementAndGet();
            // 因为拿出了一个数据，数组肯定不是满的了
            // 此时唤醒等待这notFull条件上的线程
            Thread thread = putWaiter.get(0);
            if (thread != null) {
                LockSupport.unpark(thread);
            }
            return x;
        } finally {

        }
    }

}
